#pragma once

#include "tcp_connection.h"
#include "inet_address.h"

namespace rr {
namespace nio {


class TcpClient : public std::enable_shared_from_this<TcpClient>
{
public:
    using Sptr = std::shared_ptr<TcpClient>;

    TcpClient(EventLoop::Var loop);
    ~TcpClient();

    void SetConnectionCallback(const ConnectionCallback& cb) { connection_cb_ = cb; }
    void SetConCloseCallback(const ConCloseCallback& cb) { con_close_cb_ = cb; }
    void SetMessageCallback(const MessageCallback& cb) { message_cb_ = cb; }

    int32_t Start(InetAddress& peer_addr);
    void Close(const CloseCompleteCallback &cb);
    TcpConnection::Sptr GetCoon() const { return conn_; }

private:
    static void OnConnect(uv_connect_t* req, int status);
    static void OnCloseComplete(uv_handle_t* handle);

    void DoConnect(int32_t status);
    void OnConClose(TcpConnectionVar conn);
    void DoCloseComplete();

private:
    EventLoop::Var loop_;
    TcpConnection::Sptr conn_;
    ConnectionCallback connection_cb_ = nullptr;
    ConCloseCallback con_close_cb_ = nullptr;
    CloseCompleteCallback close_complete_cb_ = nullptr;
    MessageCallback message_cb_ = nullptr;

    uv_connect_t uv_con_{};
    std::shared_ptr<uv_tcp_t> uv_tcp_handle_;
};

} //namespace 
} //namespace 